package com.itlong.cloud.utils.tool;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class HttpUtil {

    private static String makeGetParameter(HashMap<String, Object> p) {
        List<String> list = new ArrayList<>();
        for (Map.Entry<String, Object> e : p.entrySet()) {
            list.add(String.format("%s=%s", e.getKey(), e.getValue().toString()));
        }
        return String.join("&", list);
    }

    private static HashMap<String, Object> object2HashMap(Object p) {
        String json = JSONObject.toJSONString(p);
        return JSONObject.parseObject(json, new TypeReference<HashMap<String, Object>>() {
        });
    }

    public static <T> T sendGetRequestWithHashMap(RestTemplate restTemplate, String url, HashMap<String, Object> p, HashMap<String, Object> h, Class<T> responseType) {
        String fullUrl = url;
        if (p != null) {
            fullUrl = url + "?" + makeGetParameter(p);
        }
        if (h == null) {
            return restTemplate.getForObject(fullUrl, responseType);
        }
        HttpHeaders headers = new HttpHeaders();
        for (Map.Entry<String, Object> e : h.entrySet()) {
            headers.add(e.getKey(), e.getValue().toString());
        }
        HttpEntity<Object> httpEntity = new HttpEntity<>(null, headers);
        String content = restTemplate.exchange(fullUrl, HttpMethod.GET, httpEntity, String.class).getBody();
        return JSONObject.parseObject(content, responseType);
    }

    private static <T> T sendPostRequestWithForm(RestTemplate restTemplate, String url, HashMap<String, Object> p, HashMap<String, Object> h, Class<T> responseType) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        for (Map.Entry<String, Object> e : h.entrySet()) {
            headers.add(e.getKey(), e.getValue().toString());
        }
        MultiValueMap<String, Object> mvm = new LinkedMultiValueMap<>();
        for (Map.Entry<String, Object> e : p.entrySet()) {
            mvm.set(e.getKey(), e.getValue());
        }
        HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(mvm, headers);
        String content = restTemplate.postForEntity(url, httpEntity, String.class).getBody();
        return JSONObject.parseObject(content, responseType);
    }

    private static <T> T sendPostRequestWithJson(RestTemplate restTemplate, String url, HashMap<String, Object> p, HashMap<String, Object> h, Class<T> responseType) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        for (Map.Entry<String, Object> e : h.entrySet()) {
            headers.add(e.getKey(), e.getValue().toString());
        }
        HttpEntity<String> httpEntity = new HttpEntity<>(JSONObject.toJSONString(p), headers);
        String content = restTemplate.postForEntity(url, httpEntity, String.class).getBody();
        return JSONObject.parseObject(content, responseType);
    }

    public static <T> T sendGetRequestWithObject(RestTemplate restTemplate, String url, Object p, HashMap<String, Object> h, Class<T> responseType) {
        return sendGetRequestWithHashMap(restTemplate, url, object2HashMap(p), h, responseType);
    }

    public static <T> T sendPostRequestWithHashMap(RestTemplate restTemplate, String url, HashMap<String, Object> p, HashMap<String, Object> h, Class<T> responseType, boolean isJson) {
        if (isJson) {
            return sendPostRequestWithJson(restTemplate, url, p, h, responseType);
        }
        return sendPostRequestWithForm(restTemplate, url, p, h, responseType);
    }

    public static <T> T sendPostRequestWithObject(RestTemplate restTemplate, String url, Object p, HashMap<String, Object> h, Class<T> responseType, boolean isJson) {
        if (isJson) {
            return sendPostRequestWithJson(restTemplate, url, object2HashMap(p), h, responseType);
        }
        return sendPostRequestWithForm(restTemplate, url, object2HashMap(p), h, responseType);
    }

}